﻿using UnityEngine;
using System.Collections;
#if UNITY_EDITOR
using UnityEditor;
#endif
using System;
using System.Collections.Generic;

using Game.AIBehaviorTree;

[Serializable]
public class BTNodeGraph : ScriptableObject
{
    #region Public Variable
    public string GraphName = "New Tree";
    public List<BTNodeBase> nodes;
    //使用左键高亮选取的node
    public BTNodeBase selectedNode = null;
    //被框选的node
    public List<BTNodeBase> selectedNodes = new List<BTNodeBase>();
    public BTNodeBase rootNode = null;

    //树的描述信息
    public string treeDes;

    public bool wantsConnection = false;
    public BTNodeBase connectionNode;
    //BTNodeBase的序号，用于命名
    public int numNodeIndex = 0;
    //左键点击时的位置
    Vector2 posLeftDown;
    //drag时的位置
    Vector2 posDrag;
    //左键松开时的位置
    Vector2 posLeftUp;
    //是否是拖拽选框
    bool isDragSel = false;

    protected BTree tree;

    #endregion

    #region Main Methods
    void OnEnable()
    {
        if(nodes == null)
        {
            nodes = new List<BTNodeBase>();
        }
    }

    public void InitGraph()
    {
        this.tree = ScriptableObject.CreateInstance<BTree>();
        this.tree.strTreeName = this.GraphName;
        UtilsEditor.CreateAsset(this.tree, this.GraphName + ".asset", BTreeEditorData.pathTreeGameData + this.GraphName + "/");

        if (nodes.Count>0)
        {
            for(int i = 0; i< nodes.Count; i++)
            {
                nodes[i].InitNode();
            }
        }
    }

    public void addNode(BTNodeBase node)
    {
        if(this.nodes.Count == 0)
        {
            this.rootNode = node;
            this.tree.SetRoot(node.node);
        }
        this.nodes.Add(node);
        node.parentGraph = this;
        this.numNodeIndex++;
        EditorUtility.SetDirty(this);
    }

    public void removeNode(BTNodeBase node)
    {
        if(this.nodes == null || this.nodes.Count == 0)
        {
            return;
        }

        //node.removeSelf();
        if(this.nodes.Contains(node))
        {
            this.nodes.Remove(node);
        }
        EditorUtility.SetDirty(this);
    }

    public void removeRoot()
    {
        this.rootNode = null;
    }

    public void UpdateGraph()
    {
        if(nodes.Count >0)
        {

        }
    }

#if UNITY_EDITOR
    public void UpdateGraphGUI(Event e,Rect viewRect,GUISkin viewSkin)
    {
        if(nodes.Count>0)
        {
            ProcessEvents(e, viewRect);
            for (int i = 0; i < nodes.Count; i++)
            {
                nodes[i].UpdateNodeGUI(e, viewRect, viewSkin);
            }
        }

        //是否有链接正在进行
        if(wantsConnection)
        {
            if(connectionNode != null)
            {
                DrawConnectionToMouse(e.mousePosition);
            }
        }

        if(isDragSel)
        {
            this.drawRectLine(posLeftDown,posDrag);
        }
        EditorUtility.SetDirty(this);
    }

   


#endif
    #endregion

    #region Utility Methods
    private void ProcessEvents(Event e, Rect viewRect)
    {
       if(viewRect.Contains(e.mousePosition))
        {
            if(e.button == 0 && e.isMouse)
            {
                if(e.type == EventType.MouseDown)
                {
                    //Debug.Log("clickdown:"+e.clickCount);
                    this.posLeftDown = e.mousePosition;
                    this.posDrag = e.mousePosition;
                    
                    foreach(BTNodeBase node in this.nodes)
                    {
                        
                        if(node.nodeRect.Contains(e.mousePosition))
                        {
                            if(node.isSelected)
                            {
                                isDragSel = false;
                                break;
                            }
                            else
                            {
                                this.clearAllSeled();

                                node.isSelected = true;
                                this.selectedNode = node;
                                this.selectedNodes.Add(node);
                                isDragSel = false;
                                e.Use(); 
                                break;
                            }   
                        }
                        isDragSel = true;
                    }
                    if(this.selectedNodes.Count == 0)
                    {
                        isDragSel = true;
                    }

                    if(isDragSel)
                    {
                        this.clearAllSeled();
                    }
                   
                    
                }

                if (e.type == EventType.MouseDrag && e.isMouse)
                {
                    //Debug.Log("MouseDrag:"+e.clickCount);
                    if(isDragSel)
                    {
                        this.posDrag = e.mousePosition;
                        //this.drawRectLine(this.posLeftDown,e.mousePosition);
                    }
                    
                }
                if (e.type == EventType.MouseUp && e.isMouse)
                {
                   // Debug.Log("MouseUp:"+e.clickCount);
                    this.posLeftUp = e.mousePosition;
                    
                    if(isDragSel)
                    {
                       
                        this.containsNode(this.posLeftUp,this.posLeftDown);
                        e.Use();
                    }
                    isDragSel = false;
                    
                }
            }
        }
    }

    //清除所有已选node
    void clearAllSeled()
    {
         DeselectAllNodes();
        selectedNode = null;
        selectedNodes.Clear();
        wantsConnection = false;
    }

    void DeselectAllNodes()
    {
        for(int i = 0; i < nodes.Count; i++)
        {
            nodes[i].isSelected = false;
        }
    }

    private void DrawConnectionToMouse(Vector2 mousePosition)
    {
        // Handles.BeginGUI();
        // Handles.color = Color.white;
        // Handles.DrawLine(new Vector3(connectionNode.nodeRect.x + connectionNode.nodeRect.width,
        //                              connectionNode.nodeRect.y + connectionNode.nodeRect.height * 0.5f, 0f),
        //                  new Vector3(mousePosition.x,mousePosition.y,0f)            
        //                              );
        // Handles.EndGUI();
    }

    protected void drawRectLine(Vector2 startP, Vector2 endP)
    {
       // Debug.Log("startP:"+startP);
        Handles.BeginGUI();
        Handles.color = Color.green;
        Handles.DrawLine(new Vector3(startP.x,startP.y,0),
                         new Vector3(endP.x,startP.y,0f));

        Handles.DrawLine(new Vector3(startP.x,startP.y,0),
                         new Vector3(startP.x,endP.y,0f));

        Handles.DrawLine(new Vector3(startP.x,endP.y,0),
                         new Vector3(endP.x,endP.y,0f));

        Handles.DrawLine(new Vector3(endP.x,startP.y,0),
                         new Vector3(endP.x,endP.y,0f));
        Handles.EndGUI();
    }

    ///框选的两点间所选出的node
    protected void containsNode(Vector2 startP, Vector2 endP)
    {
        Rect rect = new Rect(Math.Min(startP.x,endP.x),
                             Math.Min(startP.y,endP.y),
                             Math.Abs(endP.x-startP.x),
                             Math.Abs(endP.y-startP.y));

       //较小时作为点击
       if(rect.height < 20f && rect.width < 20f)
       {
            for (int i = nodes.Count-1; i >= 0; i--)
            {
                if(nodes[i].nodeRect.Contains(startP) || nodes[i].nodeRect.Contains(endP))
                {
                    // setNode = true;
                    if(selectedNode != null)
                    {
                        selectedNode = nodes[i];
                    }
              
                    nodes[i].isSelected = true;
                    this.selectedNodes.Add(selectedNode);
                    break;
                }
            }
       }
       else
       {
           Vector2 leftDown = new Vector2(startP.x,endP.y);
           Vector2 rightTop = new Vector2(endP.x,startP.y);
           for (int i = nodes.Count-1; i >= 0; i--)
            {
                if(nodes[i].nodeRect.Contains(startP) || nodes[i].nodeRect.Contains(endP) 
                || nodes[i].nodeRect.Contains(leftDown) || nodes[i].nodeRect.Contains(rightTop)
                   || this.rectContainsRect(rect,nodes[i].nodeRect))
                {
                    this.selectedNodes.Add(nodes[i]);
                    nodes[i].isSelected = true;
                }
            }
       }
        
    }

    //first rect的线段是否穿过second rect
    protected bool rectCrossRect(Rect first, Rect second)
    {
        //超过上面
        if(second.y+second.height < first.y)
        {
            return false;
        }
        //超过下面
        if(second.y > first.y+first.height)
        {
            return false;
        }
        //超过左边
        if(second.x+second.width < first.x)
        {
            return false;
        }
        //超过右边
        if(second.x > first.x+first.width)
        {
            return false;
        }

        float button = first.y+first.height;
        float tril = first.x+first.width;

        
        if(second.x < first.x)
        {
            if(second.y > first.y && second.y+second.height < button )
            {
                return true;
            }
        }

        if(second.x+second.width > tril)
        {
            if(second.y > first.y && second.y+second.height < button )
            {
                return true;
            }
        }

        if(second.y < first.y)
        {
            if(second.x > first.x && second.x+second.width < tril )
            {
                return true;
            }
        }

        if(second.y+second.height > button)
        {
            if(second.x > first.x && second.x+second.width < tril )
            {
                return true;
            }
        }

        return false;
    }

    //first rect是否包含second rect
    protected bool rectContainsRect(Rect first, Rect second)
    {
        if(first.x <= second.x && first.y <= second.y 
        && first.x+first.width >= second.x+second.width
        && first.y+first.height >= second.y+second.height)
        {
            return true;
        }

        if(this.rectCrossRect(first,second))
        {
            return true;
        }

        return false;
    }

    ///移动被选中的节点
    public void moveSelectedNodes(Vector2 deltaPos)
    {
        foreach(BTNodeBase node in this.selectedNodes)
        {
            node.moveNode(deltaPos);
        }
    }
    #endregion

}

